package org.dromara.system.service.claim.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.ObjectUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.system.domain.claim.ClaimAttach;
import org.dromara.system.domain.claim.ClaimMain;
import org.dromara.system.domain.claim.bo.ClaimMainBo;
import org.dromara.system.domain.claim.vo.ClaimAttachVo;
import org.dromara.system.domain.claim.vo.ClaimImportVo;
import org.dromara.system.domain.claim.vo.ClaimMainVo;
import org.dromara.system.mapper.claim.ClaimAttachMapper;
import org.dromara.system.mapper.claim.ClaimMainMapper;
import org.dromara.system.service.claim.IClaimMainService;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * 理赔主Service业务层处理
 *
 * @author zj
 * @date 2025-11-16
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class ClaimMainServiceImpl implements IClaimMainService {

    private final ClaimMainMapper baseMapper;
    private final ClaimAttachMapper attachMapper;

    private final ClaimAttachServiceImpl claimAttachService;

    /**
     * 查询理赔主
     *
     * @param id 主键
     * @return 理赔主
     */
    @Override
    public ClaimMainVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询理赔主列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 理赔主分页列表
     */
    @Override
    public TableDataInfo<ClaimMainVo> queryPageList(ClaimMainBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<ClaimMain> lqw = buildQueryWrapper(bo);
        Page<ClaimMainVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        List<ClaimMainVo> records = result.getRecords();
        List<String> claimIds = records.stream().map(ClaimMainVo::getClaimId).toList();
        if (ObjectUtils.isNotEmpty(claimIds)) {
            List<ClaimAttachVo> claimAttachVoList = claimAttachService.queryListByClaimIds(claimIds);
            records.forEach(it -> {
                ClaimAttachVo claimAttachVo = claimAttachVoList.stream().filter(item -> item.getClaimId().equals(it.getClaimId())).findFirst().get();
                it.setClaimAttachVo(claimAttachVo);
            });
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的理赔主列表
     *
     * @param bo 查询条件
     * @return 理赔主列表
     */
    @Override
    public List<ClaimMainVo> queryList(ClaimMainBo bo) {
        LambdaQueryWrapper<ClaimMain> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<ClaimMain> buildQueryWrapper(ClaimMainBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<ClaimMain> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(ClaimMain::getId);
        lqw.eq(StringUtils.isNotBlank(bo.getClaimId()), ClaimMain::getClaimId, bo.getClaimId());
        lqw.eq(StringUtils.isNotBlank(bo.getBusinessSource()), ClaimMain::getBusinessSource, bo.getBusinessSource());
        lqw.eq(StringUtils.isNotBlank(bo.getJdReportId()), ClaimMain::getJdReportId, bo.getJdReportId());
        lqw.eq(StringUtils.isNotBlank(bo.getReportTime()), ClaimMain::getReportTime, bo.getReportTime());
        lqw.eq(StringUtils.isNotBlank(bo.getOccurrenceTime()), ClaimMain::getOccurrenceTime, bo.getOccurrenceTime());
        lqw.eq(StringUtils.isNotBlank(bo.getCloseTime()), ClaimMain::getCloseTime, bo.getCloseTime());
        lqw.eq(StringUtils.isNotBlank(bo.getReportMethod()), ClaimMain::getReportMethod, bo.getReportMethod());
        lqw.eq(StringUtils.isNotBlank(bo.getPerformanceType()), ClaimMain::getPerformanceType, bo.getPerformanceType());
        lqw.eq(StringUtils.isNotBlank(bo.getDamageDegree()), ClaimMain::getDamageDegree, bo.getDamageDegree());
        lqw.eq(StringUtils.isNotBlank(bo.getFirstLevelReason()), ClaimMain::getFirstLevelReason, bo.getFirstLevelReason());
        lqw.eq(StringUtils.isNotBlank(bo.getSecondLevelReason()), ClaimMain::getSecondLevelReason, bo.getSecondLevelReason());
        lqw.eq(StringUtils.isNotBlank(bo.getReporter()), ClaimMain::getReporter, bo.getReporter());
        lqw.eq(StringUtils.isNotBlank(bo.getReporterPhone()), ClaimMain::getReporterPhone, bo.getReporterPhone());
        lqw.eq(StringUtils.isNotBlank(bo.getSender()), ClaimMain::getSender, bo.getSender());
        lqw.eq(StringUtils.isNotBlank(bo.getSenderPhone()), ClaimMain::getSenderPhone, bo.getSenderPhone());
        lqw.eq(StringUtils.isNotBlank(bo.getSenderAddress()), ClaimMain::getSenderAddress, bo.getSenderAddress());
        lqw.eq(StringUtils.isNotBlank(bo.getPaymentMethod()), ClaimMain::getPaymentMethod, bo.getPaymentMethod());
        lqw.eq(StringUtils.isNotBlank(bo.getPolicyId()), ClaimMain::getPolicyId, bo.getPolicyId());
        lqw.eq(StringUtils.isNotBlank(bo.getPolicyStartTime()), ClaimMain::getPolicyStartTime, bo.getPolicyStartTime());
        lqw.eq(StringUtils.isNotBlank(bo.getPolicyEndTime()), ClaimMain::getPolicyEndTime, bo.getPolicyEndTime());
        lqw.eq(StringUtils.isNotBlank(bo.getExtendedWarrantyOrderId()), ClaimMain::getExtendedWarrantyOrderId, bo.getExtendedWarrantyOrderId());
        lqw.eq(StringUtils.isNotBlank(bo.getMerchantId()), ClaimMain::getMerchantId, bo.getMerchantId());
        lqw.eq(StringUtils.isNotBlank(bo.getShopId()), ClaimMain::getShopId, bo.getShopId());
        lqw.like(StringUtils.isNotBlank(bo.getShopName()), ClaimMain::getShopName, bo.getShopName());
        lqw.like(StringUtils.isNotBlank(bo.getInsuranceName()), ClaimMain::getInsuranceName, bo.getInsuranceName());
        lqw.eq(StringUtils.isNotBlank(bo.getMainOrderId()), ClaimMain::getMainOrderId, bo.getMainOrderId());
        lqw.eq(StringUtils.isNotBlank(bo.getMainOrderCreateTime()), ClaimMain::getMainOrderCreateTime, bo.getMainOrderCreateTime());
        lqw.eq(StringUtils.isNotBlank(bo.getMainOrderOutboundTime()), ClaimMain::getMainOrderOutboundTime, bo.getMainOrderOutboundTime());
        lqw.eq(StringUtils.isNotBlank(bo.getMainOrderCompleteTime()), ClaimMain::getMainOrderCompleteTime, bo.getMainOrderCompleteTime());
        lqw.like(StringUtils.isNotBlank(bo.getMainCommodityName()), ClaimMain::getMainCommodityName, bo.getMainCommodityName());
        lqw.eq(StringUtils.isNotBlank(bo.getMainCommoditySku()), ClaimMain::getMainCommoditySku, bo.getMainCommoditySku());
        lqw.eq(StringUtils.isNotBlank(bo.getMainCommodityImei()), ClaimMain::getMainCommodityImei, bo.getMainCommodityImei());
        lqw.eq(StringUtils.isNotBlank(bo.getBrand()), ClaimMain::getBrand, bo.getBrand());
        lqw.eq(StringUtils.isNotBlank(bo.getModel()), ClaimMain::getModel, bo.getModel());
        lqw.like(StringUtils.isNotBlank(bo.getFirstCategoryName()), ClaimMain::getFirstCategoryName, bo.getFirstCategoryName());
        lqw.like(StringUtils.isNotBlank(bo.getSecondCategoryName()), ClaimMain::getSecondCategoryName, bo.getSecondCategoryName());
        lqw.like(StringUtils.isNotBlank(bo.getThirdCategoryName()), ClaimMain::getThirdCategoryName, bo.getThirdCategoryName());
        lqw.eq(StringUtils.isNotBlank(bo.getInsuranceCode()), ClaimMain::getInsuranceCode, bo.getInsuranceCode());
        lqw.like(StringUtils.isNotBlank(bo.getInsuranceCodeName()), ClaimMain::getInsuranceCodeName, bo.getInsuranceCodeName());
        lqw.eq(StringUtils.isNotBlank(bo.getRating()), ClaimMain::getRating, bo.getRating());
        lqw.eq(StringUtils.isNotBlank(bo.getCloseType()), ClaimMain::getCloseType, bo.getCloseType());
        lqw.like(StringUtils.isNotBlank(bo.getRepairerName()), ClaimMain::getRepairerName, bo.getRepairerName());
        lqw.like(StringUtils.isNotBlank(bo.getStoreName()), ClaimMain::getStoreName, bo.getStoreName());
        lqw.eq(StringUtils.isNotBlank(bo.getDispatchTime()), ClaimMain::getDispatchTime, bo.getDispatchTime());
        lqw.eq(StringUtils.isNotBlank(bo.getAcceptTime()), ClaimMain::getAcceptTime, bo.getAcceptTime());
        lqw.eq(StringUtils.isNotBlank(bo.getCustomerSendTime()), ClaimMain::getCustomerSendTime, bo.getCustomerSendTime());
        lqw.eq(StringUtils.isNotBlank(bo.getExpressNo()), ClaimMain::getExpressNo, bo.getExpressNo());
        lqw.eq(StringUtils.isNotBlank(bo.getReceiveMachineTime()), ClaimMain::getReceiveMachineTime, bo.getReceiveMachineTime());
        lqw.eq(StringUtils.isNotBlank(bo.getPlanSubmitTime()), ClaimMain::getPlanSubmitTime, bo.getPlanSubmitTime());
        lqw.eq(StringUtils.isNotBlank(bo.getPerformanceCompleteTime()), ClaimMain::getPerformanceCompleteTime, bo.getPerformanceCompleteTime());
        lqw.eq(StringUtils.isNotBlank(bo.getProcurementChannel()), ClaimMain::getProcurementChannel, bo.getProcurementChannel());
        lqw.eq(StringUtils.isNotBlank(bo.getNewMachineOrderId()), ClaimMain::getNewMachineOrderId, bo.getNewMachineOrderId());
        lqw.eq(StringUtils.isNotBlank(bo.getFileTime()), ClaimMain::getFileTime, bo.getFileTime());
        lqw.eq(StringUtils.isNotBlank(bo.getCloseStatus()), ClaimMain::getCloseStatus, bo.getCloseStatus());
        lqw.eq(StringUtils.isNotBlank(bo.getIsResidualRecovered()), ClaimMain::getIsResidualRecovered, bo.getIsResidualRecovered());
        lqw.eq(StringUtils.isNotBlank(bo.getIsClaimPaid()), ClaimMain::getIsClaimPaid, bo.getIsClaimPaid());
        lqw.eq(StringUtils.isNotBlank(bo.getIsResidualAuctioned()), ClaimMain::getIsResidualAuctioned, bo.getIsResidualAuctioned());
        lqw.eq(bo.getFinalPaymentAmount() != null, ClaimMain::getFinalPaymentAmount, bo.getFinalPaymentAmount());
        lqw.orderByAsc(ClaimMain::getReportDate);
        return lqw;
    }

    /**
     * 新增理赔主
     *
     * @param bo 理赔主
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(ClaimMainBo bo) {
        ClaimMain add = MapstructUtils.convert(bo, ClaimMain.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改理赔主
     *
     * @param bo 理赔主
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(ClaimMainBo bo) {
        ClaimMain update = MapstructUtils.convert(bo, ClaimMain.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(ClaimMain entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除理赔主信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    @Override
    public ClaimMainVo getInfoById(Long id) {
        ClaimMainVo claimMainVo = this.queryById(id);
        List<ClaimAttachVo> claimAttachVoList = claimAttachService.queryListByClaimIds(Collections.singletonList(claimMainVo.getClaimId()));
        if (ObjectUtils.isNotEmpty(claimAttachVoList)) {
            claimMainVo.setClaimAttachVo(claimAttachVoList.get(0));
        }
        return claimMainVo;
    }

    @Override
    public void saveBatch(List<ClaimImportVo> list) {
        Date reportDate = new Date();
        List<ClaimMain> claimMains = MapstructUtils.convert(list, ClaimMain.class);
        if (CollectionUtils.isEmpty(claimMains)) {
            return;
        }
        for (ClaimMain claimMain : claimMains) {
            claimMain.setReportDate(reportDate);
        }
        baseMapper.insertBatch(claimMains);

        List<ClaimAttach> claimAttachList = MapstructUtils.convert(list, ClaimAttach.class);
        attachMapper.insertBatch(claimAttachList);
    }
}
